package org.EasyDevelop.Builder;

import org.EasyDevelop.Bean.Constants;
import org.EasyDevelop.Bean.FieldInfo;
import org.EasyDevelop.Bean.TableInfo;
import org.EasyDevelop.Utils.PropertiesUtils;
import org.EasyDevelop.Utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.List;
import java.util.Map;

public class ServiceBuilder {
    private static Logger logger = LoggerFactory.getLogger(ServiceBuilder.class);

    public static void execute(TableInfo tableInfo){
        File folder = new File(Constants.PATH_SERVICE);

        if(!folder.exists()) folder.mkdirs();
        String className = tableInfo.getBeanName() + StringUtils.upperCaseFirstLetter(Constants.SUFFIX_MAP.get("service"));
        File poFile = new File(folder, className + Constants.SUFFIX_MAP.get("java"));

        OutputStream os = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            os = new FileOutputStream(poFile);
            osw = new OutputStreamWriter(os, "UTF8");
            bw = new BufferedWriter(osw);

            //package
            bw.write("package " + Constants.PACKAGE_SERVICE + ";");
            bw.newLine();
            bw.newLine();

            //import

            //Bean and BeanQuery
            bw.write("import " + Constants.PACKAGE_PO + "." + tableInfo.getBeanName() + ";");
            bw.newLine();
            bw.write("import " + Constants.PACKAGE_QUERY + "." + tableInfo.getBeanParamName() + ";");
            bw.newLine();

            //List
            bw.write("import java.util.List;");
            bw.newLine();

            //PaginationResVo
            bw.write("import " + Constants.PACKAGE_ENTITY_VO_PAGINATIONRESVO + ".PaginationResVo;");
            bw.newLine();

            //date
            if(tableInfo.getHaveDate() || tableInfo.getHaveDateTime()){
                bw.write("import java.util.Date;");
                bw.newLine();
            }
            //bigDecimal
            if(tableInfo.getHaveBigDecimal()){
                bw.write("import java.math.BigDecimal;");
                bw.newLine();
            }

            //class
            bw.write("public interface " + className + " {");
            bw.newLine();

            //Method

            //list
            CommentBuilder.createMethodComment(bw,"根据条件查询列表");
            bw.write("\tList<" + tableInfo.getBeanName() + "> findListByParam(" + tableInfo.getBeanParamName() + " query);");
            bw.newLine();
            bw.newLine();
            //count
            CommentBuilder.createMethodComment(bw,"根据条件查询数量");
            bw.write("\tLong findCountByParam(" + tableInfo.getBeanParamName() + " query);");
            bw.newLine();
            bw.newLine();
            //pageList
            CommentBuilder.createMethodComment(bw,"根据条件分页查询列表");
            bw.write("\tPaginationResVo<" + tableInfo.getBeanName() + "> findListByPage(" + tableInfo.getBeanParamName() + " query);");
            bw.newLine();
            bw.newLine();
            //addBatch
            CommentBuilder.createMethodComment(bw,"批量新增");
            bw.write("\tLong addBatch(List<" + tableInfo.getBeanName() + "> list);");
            bw.newLine();
            bw.newLine();
            //add
            CommentBuilder.createMethodComment(bw,"新增");
            bw.write("\tLong add(" + tableInfo.getBeanName() + " bean);");
            bw.newLine();
            bw.newLine();

            //addOrUpdate
            CommentBuilder.createMethodComment(bw,"新增");
            bw.write("\tLong addOrUpdate(" + tableInfo.getBeanName() + " bean);");
            bw.newLine();
            bw.newLine();

            //addOrUpdate
            CommentBuilder.createMethodComment(bw,"新增");
            bw.write("\tLong addOrUpdateBatch(List<" + tableInfo.getBeanName() + "> list);");
            bw.newLine();
            bw.newLine();

            generatedIdMethods(bw,tableInfo);

            bw.write("}");
            bw.newLine();

            bw.flush();

        } catch (Exception e) {
            logger.error("创建Service文件失败,{}",e);
        } finally {
            if(bw!=null)
                try{
                    bw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            if(osw!=null)
                try{
                    osw.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            if(os!=null)
                try{
                    os.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
        }

    }

    private static void generatedIdMethods(BufferedWriter bw, TableInfo tableInfo) throws IOException {
        StringBuilder methodParams = new StringBuilder();
        StringBuilder methodName = new StringBuilder();
        for (Map.Entry<String, List<FieldInfo>> entry : tableInfo.getKeyIndexMap().entrySet()) {
            List<FieldInfo> keyFieldList = entry.getValue();

            //叠加索引相关值
            Integer idx = 0;
            for (FieldInfo fieldInfo : keyFieldList) {
                methodName.append(StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName()));
                methodParams.append(
                    fieldInfo.getJavaType() + " " +
                    StringUtils.upperCaseFirstLetter(fieldInfo.getPropertyName())
                );
                if(idx++<keyFieldList.size()-1){
                    methodName.append("And");
                    methodParams.append(", ");
                }
            }

            //select
            CommentBuilder.createMethodComment(bw,"根据" + methodName + "查询");
            bw.write("\t" + tableInfo.getBeanName() + " getBy" + methodName.toString());
            bw.write("(");
            bw.write(methodParams.toString());
            bw.write(");");
            bw.newLine();
            bw.newLine();

            //update
            CommentBuilder.createMethodComment(bw,"根据" + methodName + "更新");
            bw.write("\tLong updateBy" + methodName.toString());
            bw.write("(");
            bw.write(tableInfo.getBeanName() + " bean, ");
            bw.write(methodParams.toString());
            bw.write(");");
            bw.newLine();
            bw.newLine();

            //delete
            CommentBuilder.createMethodComment(bw,"根据" + methodName + "删除");
            bw.write("\tLong deleteBy" + methodName.toString());
            bw.write("(");
            bw.write(methodParams.toString());
            bw.write(");");
            bw.newLine();
            bw.newLine();


            methodName = new StringBuilder();
            methodParams = new StringBuilder();
        }


    }


}
